package car;

//  -------------   JOGL SampleProgram  (Ellipse) ------------

import javax.media.opengl.*;

import Wagen.Wagen;

import com.sun.opengl.util.FPSAnimator;

import java.awt.*;
import java.awt.event.*;
public class Car
       implements WindowListener, GLEventListener, MouseMotionListener, KeyListener
{
	private GLCanvas canvas;		//OpenGL-Canvas
	private double xmin = -20;
	private double xmax = 20;
	private double ymin = -3;
	private double ymax = 3;
	private double mx = 0;
	private double my = 0;
	private Wagen wagen;
	
	//Winkelgeschwindigkeit
	double omega = 2;		//phi
	double r =	4;
	double t,dt=0.01;
	private double accx = 0;
	private double accy = 0;

	private FPSAnimator anim;
    
	//  ------------------  Methoden  --------------------

	// Koordinatenachsen zeichnen
     void zeichneAchsen(GL gl)                                  
     {  gl.glBegin(GL.GL_LINES);
    // x-Achse
        gl.glVertex2d(xmin,0);        
        gl.glVertex2d(xmax,0);
        gl.glVertex2d(0,ymin);        
    // y-Achse
        gl.glVertex2d(0,ymax);
        gl.glEnd();
     }

     void zeichneRad(GL gl){
    	 double u = 0.4;
    	 double v = 0.2;
    	 gl.glBegin(GL.GL_POLYGON);
         gl.glVertex2d(-u,-v);
         gl.glVertex2d(u, -v);
         gl.glVertex2d(u, v);
         gl.glVertex2d(-u, v);
         gl.glEnd();
     }
     void zeichneWagen(GL gl)                                    
     {  
    	 double a1 = 0.5;
    	 double a2 = 2.5;
    	 double b = 1.5;
    	 
//    	 gl.glMatrixMode(GL.GL_MODELVIEW);
//    	 gl.glTranslated(t * 1, 0, 0);
//    	 gl.glRotated(t * 10, 0, 1, 0);
    	 gl.glBegin(GL.GL_POLYGON);
         gl.glVertex2d(-a1,-b);
         gl.glVertex2d(a2, -b);
         gl.glVertex2d(a2, b);
         gl.glVertex2d(-a1, b);
         gl.glEnd();
         gl.glTranslated(0, 1.4*b, 0);
         zeichneRad(gl);
         gl.glTranslated(1.4 * b, 0, 0);
         zeichneRad(gl);
         gl.glTranslated(-1.4 * b, -2.8 * b,0);
         zeichneRad(gl);
         gl.glTranslated(1.4 * b, 0,0);
         zeichneRad(gl);
         //man muesste hier die Modelview Matrix wieder zuruecksetzen oder mit dem MatrixStack, push und pop
         gl.glLoadIdentity();
     }


     // Konstruktor
     public Car()
     {  
    	Frame f = new Frame("Car Demo");
        f.setSize(800, 600);
        f.addWindowListener(this);
        // OpenGL-Window
        canvas = new GLCanvas();
        wagen = new Wagen(2, 0);
        canvas.addKeyListener(this);
        canvas.addGLEventListener(this);
        canvas.addMouseMotionListener(this);
        f.add(canvas);
        f.setVisible(true);
        canvas.requestFocus();
     }


     public static void main(String[] args)                     // main-Methode der Applikation
     {  new Car();
     }


     //  ---------  OpenGL-Events  -----------------------

     public void init(GLAutoDrawable drawable)
     {  GL gl = drawable.getGL();                               // OpenGL-Objekt
        gl.glClearColor(0.0f, 0.0f, 0.3f, 0.3f);                // erasing color
        anim = new FPSAnimator(drawable, 200, true);
        anim.start();
     }


	public void display(GLAutoDrawable drawable) {
		GL gl = drawable.getGL();
		gl.glClear(GL.GL_COLOR_BUFFER_BIT); // Bild loeschen
		gl.glMatrixMode(GL.GL_MODELVIEW);
//		gl.glLoadIdentity();
		//Animation des Autos, es wird jedesmal von Afang an ausgegangen, d.h. mit LoadIdentity beginnt man immer ganz von vorne
		gl.glColor3d(0, 1, 1);
//		zeichneAchsen(gl);
		gl.glColor3d(1, 1, 0.1);
		gl.glPolygonMode(GL.GL_FRONT_AND_BACK, GL.GL_LINE);
		wagen.zeichne(gl);
		wagen.move(gl, dt);
		gl.glColor3d(0, 1, 1); // Zeichenfarbe
		// t wir zeichnen den Kreis jeweils immer zu einer gewissen Zeit
//		t += 2*dt;
	}


     public void reshape(GLAutoDrawable drawable,               // Window resized
                         int x, int y,
                         int width, int height)
     {  GL gl = drawable.getGL();
     //damit keine Verzerrungen enstehen
     	ymax = xmax * height / width;
     	ymin = -ymax;
     	gl.glMatrixMode(GL.GL_PROJECTION);
     	gl.glLoadIdentity();
        gl.glOrtho(xmin, xmax, ymin, ymax, -1, 1);
        gl.glViewport(0, 0, width, height);
     }


     public void displayChanged(GLAutoDrawable drawable,
                                boolean modeChanged,
                                boolean deviceChanged)
     { }


     //  ---------  Window-Events  --------------------

     public void windowClosing(WindowEvent e)
     {  System.exit(0);
     }
     public void windowActivated(WindowEvent e) {  }
     public void windowClosed(WindowEvent e) {  }
     public void windowDeactivated(WindowEvent e) {  }
     public void windowDeiconified(WindowEvent e) {  }
     public void windowIconified(WindowEvent e) {  }
     public void windowOpened(WindowEvent e) {  }

 	//  ---------  Mouse Events  --------------------

 	@Override
 	public void mouseDragged(MouseEvent e) {
 		NormalizeCoordinates(e);
 	}


 	@Override
 	public void mouseMoved(MouseEvent e) {
 		//Calculate Acceleration
 		double tmpx = this.mx;
 		double tmpy = this.my;
 		NormalizeCoordinates(e);
 		this.accx = tmpx - this.mx;
 		this.accy = tmpy - this.my;
 		System.out.println("Acc: "+this.accx+" "+this.accy);
 	}

	
	private void NormalizeCoordinates(MouseEvent e){
		double x = e.getX();
		double y = e.getY();
		//0-Punkt im KoordiantenNetz bestimmen
		double x0 = canvas.getWidth()/2 + canvas.getX();
		double y0 = canvas.getHeight()/2 - canvas.getY();
		System.out.println();
		System.out.printf("0 Punkt liegt in %f / %f",x0,y0);
		double modifierx = 1;
		double modifiery = 1;
		double lengthratio = xmax / (canvas.getWidth() - x0);
		double heightratio = ymax / (canvas.getHeight() - y0);
		double normalizedlength = Math.abs((x-x0) * lengthratio);
		double normalizedheight = Math.abs((y-y0) * heightratio);
		System.out.println();
		System.out.printf("Normalized Length: %f, Normalized height: %f",normalizedlength,normalizedheight);
		if (x < x0) modifierx = -1;
		if (y > y0) modifiery = -1;
		this.mx = 0 + normalizedlength * modifierx;
		this.my = 0 + normalizedheight * modifiery;
		System.out.println();
		System.out.println("mx: "+ this.mx + " my: "+ this.my);
	}


	@Override
	public void keyPressed(KeyEvent e) {
		switch (e.getKeyCode()) {
		case KeyEvent.VK_S:
				if (anim.isAnimating()) {
					anim.stop();
				} else {
					anim.start();
				}
			break;
		case KeyEvent.VK_UP:
				omega*=2;
			break;
		case KeyEvent.VK_DOWN:
				omega/=2;
			break;
		case KeyEvent.VK_LEFT:
				wagen.lenkung(0.1);
			break;
		case KeyEvent.VK_RIGHT:
				wagen.lenkung(-0.1);
			break;	
		default:
			break;
		}
	}

	@Override
	public void keyReleased(KeyEvent e) {
		// TODO Auto-generated method stub
		
	}


	@Override
	public void keyTyped(KeyEvent e) {

	}

  }